package com.ping.study.service.tx;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TxSportTokenRefreshService {

    private final WebClient webClient;
    private final StringRedisTemplate redisTemplate;
    private final ObjectMapper objectMapper = new ObjectMapper();
    private static final String REDIS_COOKIE_MAP_KEY = "tx_sports_cookie_map";

    public TxSportTokenRefreshService(WebClient.Builder builder,
                                      StringRedisTemplate redisTemplate) {
        this.webClient = builder.baseUrl("https://app.sports.qq.com").build();
        this.redisTemplate = redisTemplate;
    }

    public boolean refreshCookies() {
        try {
            String cookieJson = redisTemplate.opsForValue().get(REDIS_COOKIE_MAP_KEY);
            if (cookieJson == null) {
                log.error("Redis 中未找到 Cookie，无法刷新");
                return false;
            }
            log.info("旧的cookie：{}",cookieJson);

            Map<String, String> baseCookies = objectMapper.readValue(cookieJson, new TypeReference<>() {});
            String cookieHeader = buildCookieHeader(baseCookies);

            String response = webClient.get()
                    .uri("/init/refresh?os=web")
                    .header("Cookie", cookieHeader)
                    .retrieve()
                    .bodyToMono(String.class)
                    .block();

            JsonNode data = objectMapper.readTree(response).path("data");
            Map<String, String> newCookies = extractNewCookieMap(data);

            baseCookies.putAll(newCookies);

            redisTemplate.opsForValue().set(
                    REDIS_COOKIE_MAP_KEY,
                    objectMapper.writeValueAsString(baseCookies),
                    Long.parseLong(data.path("tokenTTL").asText()),
                    TimeUnit.SECONDS
            );
            return true;
        } catch (Exception e) {
            log.error("刷新 Cookie 失败", e);
            return false;
        }
    }

    private Map<String, String> extractNewCookieMap(JsonNode dataNode) {
        Map<String, String> result = new HashMap<>();
        if (dataNode != null && dataNode.has("cookie")) {
            for (JsonNode cookie : dataNode.get("cookie")) {
                result.put(cookie.get("name").asText(), cookie.get("value").asText());
            }
        }
        return result;
    }

    private String buildCookieHeader(Map<String, String> cookieMap) {
        return cookieMap.entrySet().stream()
                .map(e -> e.getKey() + "=" + e.getValue())
                .collect(Collectors.joining("; "));
    }

    // 可选：定时自动刷新（你可以打开）
    @Scheduled(fixedRate = 5400000) // 每90分钟执行一次
    public void scheduledRefresh() {
        log.info("定时刷新Cookie");
        if (!refreshCookies()) {
            log.warn("Cookie 刷新失败，Redis 中可能缺失数据");
        }
    }
}
